#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "cmd.h"
#include <mh/common.h>
#include <mh/probe.h>
#include "pthread.h"
#include "udp.h"
#include "carriage.h"
#include "sink_setting.h"
#include "camsetting.h"

#ifndef _INET_VERSION

/* knit complete,0编织没有开始，１编织中，２编织完成 */
#define KNIT_PREARE     (0x00 << 1)
#define KNITING         (0x01 << 1)
#define KNIT_COMPLETE   (0X01 << 2)

#define LOOP_KC_BIT         (0x03 << 1)
/* side yarn */
#define LOOP_SY_BIT         (0x01 << 3)
/* yarn carrier */
#define LOOP_YC_BIT         (0x01 << 4)
/* need loop bit */
#define LOOP_NL_BIT         (0x01 << 5)
/* is front refused yarn */
#define LOOP_FRY_BIT        (0x01 << 6)
/* is back refused yarn */
#define LOOP_BRY_BIT        (0x01 << 7)


enum { TH_STATE_PAUSE = 0, TH_STATE_RUN, TH_STATE_EXIT };
typedef  enum {SPEED_HIGH = 0, SPEED_LIMIT, SPEED_LOW, SPEED_INCH
} RUN_SPEED_TYPE;
typedef enum {
    STATE_NONE = 0, STATE_RESET, STATE_RESET_STEP1, STATE_RESET_STEP2, STATE_STOP,
    STATE_RUN, STATE_RUN_SLOW, STATE_WAIT_STOP, STATE_RUN_BEFORE, STATE_KNOT
} RUN_STATE_TYPE;
enum {
    RESET_FINISHED = 1,
};

typedef struct {
    PROBE_DATA *probe_data;
    int send_state;
    uchar th_request;
    uchar th_state;
    uchar direction;
    uchar hangding;
    pthread_mutex_t udp_mutex;//g_udp_mutex
    int run_line_change;//draw_all
    int run_line;//current_line
    ushort cycle_start;
    ushort cycle_end;
    ushort cycle_times;
    uchar mac_speed_state;//mac_state;
    uchar sys_state;
    int needle;
    int error_code;
    int need_loop;
    int need_loop_record;
    uchar yarn_used[GAUZE_NUM];
    KNIT_PAGE *pcon;
    uchar reset_finished;
    MH_UDP st_udp;
    uchar cam;
    QUERY_FB_IN_RUN_RESP resp;
    pthread_t th_run;
    short rock_pos; //运行状态摇床的位置
}MACHINE, *PMACHINE;

int program_send_file(PMH_UDP pudp, KNIT_PAGE *con_buf, unsigned short line);
int pe_send_file(PMH_UDP pudp, uchar *buf, ushort width, ushort height);
int speed_send_file(PMH_UDP pudp, PMH_SPEED speed_array, pthread_mutex_t *pudp_mutex);
int dumu_send_file(PMH_UDP pudp, PMH_DUMU dumu_array, pthread_mutex_t *pudp_mutex);
int yarn_exchange_send_file(PMH_UDP pudp, PYARN_EXCHANGE yarn_exchange, pthread_mutex_t *pudp_mutex);
int sysprm_send_file(PMH_UDP pudp, PSYS_PARAM psys_param);
int workprm_send_file(PMH_UDP pudp, PWORK_PARAM pwork_param);
int hideprm_send_file(PMH_UDP pudp, PHIDE_PARAM phide_param);
int rock_send_file(PMH_UDP pudp, PROCK_POS prock_pos, pthread_mutex_t *pudp_mutex);
int dmbz_send_file(PMH_UDP pudp, PSTITCH_AMEND psa, pthread_mutex_t *pudp_mutex);
int yarn_stop_send_file(PMH_UDP pudp, PYARN_STOP yarn_stop);
int extpiece_send_file(PMH_UDP pudp, PEXT_PIECE extpiece, pthread_mutex_t *pudp_mutex);
int yarn_before_send_file(PMH_UDP pudp, PYARN_BEFORE_NEEDLE pyarn_before_needle);
int macparam_send_file(PMH_UDP pudp, PMAC_PARAM pmac_param);
int alarmmask_send_file(PMH_UDP pudp, PALARM_MASK palarm, pthread_mutex_t *pudp_mutex);
int sink_send_file(PMH_UDP pudp, SINK_PIECE sinkdata, pthread_mutex_t *pudp_mutex);
int yarn_feed_send_file(PMH_UDP pudp, YARNFEEDER_PIECE yarndata, pthread_mutex_t *pudp_mutex);
int cam_send_file(PMH_UDP pudp, CAM_PIECE camdata, pthread_mutex_t *pudp_mutex);
int board_param_send_file(PMH_UDP pudp, PBOARD_PARAM boarddata, pthread_mutex_t *pudp_mutex);
int jijia_upgrade_send_file(PMH_UDP pudp, uchar *data, int file_size, pthread_mutex_t *pudp_mutex);
/*
 * init machine object
 * param cam: cams of system, from 1 to 4
 */
PMACHINE CreateMachine(uchar cam)
{
    PMACHINE pmac = calloc(1, sizeof(MACHINE));
    if(pmac)
    {
        if(udp_init(&(pmac->st_udp)))
        {
            printf("failed to init inet udp\n");
            free(pmac);
            return NULL;
        }
        if(pthread_mutex_init(&pmac->udp_mutex, NULL))
        {
            printf("failed to init udp mutex\n");
            free(pmac);
            return NULL;
        }
        pmac->cam = cam;
    }
    return pmac;
}
/*
 * destroy machine object
 */
void DestroyMachine(PMACHINE pmac)
{
    if(pmac->probe_data)
    {
        free(pmac->probe_data);
    }
    pmac->th_request = TH_STATE_EXIT;
//    pthread_join(pmac->th_run, NULL);   //**回收后无法升级主程序
    udp_close(&pmac->st_udp);
    pthread_mutex_destroy(&pmac->udp_mutex);
}
/*
 * create probe data
 */
PROBE_DATA* MacCreateProbe(PMACHINE pmac)
{
    pmac->probe_data = calloc(1, sizeof(PROBE_DATA));
    if(pmac->probe_data)
    {
        pmac->probe_data->pudp_mutex = &pmac->udp_mutex;
        pmac->probe_data->psend_state = &pmac->send_state;
        pmac->probe_data->pudp = &pmac->st_udp;
        pmac->probe_data->cam = pmac->cam;
    }
    return pmac->probe_data;
}


/*
 * all of below be which to send by machine
 * all be message of can which is command of yarn, selector...
 * all this send by can through machine
 */
/*
 * message of can sent by machine about selector
 */
int MacToggleSelect(PMACHINE pmac, uchar *data, int size)
{
    int ret = 0;
    int retry = 1;
    REQUEST_CAN request;
    request.cmd = CMD_REQUEST_CAN;
    request.id = 0x05;
    request.len = size;
 /*   for(i = 0; i < size; ++i)
    {
        request.data[i] = data[i];
    printf("0x%x ",data[i]);
    }     //*/

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
 *
 */
CARRIAGE * MacCarriageNew(PMACHINE pmac,  int handle)
{
    return carriage_new(&pmac->st_udp, handle);
}
/*
 *
 */
 SINK_SETTING * MacSinkSettingNew(PMACHINE pmac)
 {
     return sink_setting_new(&pmac->st_udp);
 }
 /*
 *
 */
 CAM_SETTING * MacCamSettingNew(PMACHINE pmac)
 {
     return cam_setting_new(&pmac->st_udp);
 }
/*
 * reset select
 */
int MacResetSelect(PMACHINE pmac, uchar *data, int size)
{
    int ret = 0;
    int retry = 1;
    int i  =0;
    REQUEST_CAN request;
    request.cmd = CMD_REQUEST_CAN;
    request.id = 0x06;
    request.len = size;
    for(i = 0; i < size; ++i)
    {
        request.data[i] = data[i];
    }
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*) &request, sizeof(request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }
    return ret;
}
/*
 * message of can sent by machine about yarn
 */
int MacToggleYarn(PMACHINE pmac, uchar *data, int size)
{
    int retry = 1;
    int ret = 0;
    REQUEST_CAN request;

    request.cmd = CMD_REQUEST_CAN;
    request.id = 0x00;
    request.len = size;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
 * reset yarn
 */
int MacResetYarn(PMACHINE pmac, uchar *data, int size)
{
    int ret = 0;
    int retry = 1;
    int i = 0;

    REQUEST_CAN request;
    request.cmd = CMD_REQUEST_CAN;
    request.id = 0x01;
    request.len = size;
    for(i = 0; i < size; ++i)
    {
        request.data[i] = data[i];
    }
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*) &request, sizeof(request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }
    return ret;
}
/*
 * message of can sent by machine about cam
 */
int MacToggleCam(PMACHINE pmac, uchar *data, int size)
{
    int retry = 1;
    int ret = 0;
    REQUEST_CAN request;

    request.cmd = CMD_REQUEST_CAN;
    request.id = 0x04;
    request.len = size;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
 * reset cam
 */
int MacResetCam(PMACHINE pmac, uchar *data, int size)
{
    int ret = 0;
    int retry = 1;
    int i = 0;

    REQUEST_CAN request;
    request.cmd = CMD_REQUEST_CAN;
    request.id = 0x03;
    request.len = size;
    for(i = 0; i < size; ++i)
    {
        request.data[i] = data[i];
    }

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }
    return ret;
}
/*
 * message of can sent by machine about stitch
 */
int MacToggleStitch(PMACHINE pmac, uchar *data, int size, char id)
{
    int retry = 1;
    int ret = 0;
    REQUEST_CAN request = { 0 };
    request.cmd = CMD_REQUEST_CAN;
    request.id = id;
    request.len = size;
    memcpy(request.data, data, size);
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
 * get state of machine head
 */
int MacGetHeader(PMACHINE pmac, HEAD_TEST *phead_test)
{
    int ret = 0;
    int retry = 3;
    short query = CMD_QUERY_FB_IN_CTEST;
    QUERY_FB_IN_CTEST_RESP resp;
    memset(&resp, 0, sizeof(resp));
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_query(&pmac->st_udp, (uchar*)&query, sizeof (query), (RESPONSE*)&resp, sizeof (resp));
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        if(retry-- > 0)
        {
            goto RETRY;
        }
    }
    else
    {
        memset(phead_test, 0, sizeof(phead_test));
        phead_test->error = resp.cerror;
        phead_test->yarn_state[0] = resp.yc_state[0];
        phead_test->yarn_state[1] = resp.yc_state[1];
        phead_test->cam_state[0][0] = resp.cam_state[0];
        phead_test->cam_state[1][0] = resp.cam_state[1];
        phead_test->cam_state[0][1] = resp.cam_state[2];
        phead_test->cam_state[1][1] = resp.cam_state[3];
        phead_test->select_state[0][0] = resp.sel_state[0];
        phead_test->select_state[0][1] = resp.sel_state[1];
        phead_test->select_state[1][0] = resp.sel_state[2];
        phead_test->select_state[1][1] = resp.sel_state[3];
        phead_test->select_state[0][2] = resp.sel_state[4];
        phead_test->select_state[0][3] = resp.sel_state[5];
        phead_test->select_state[1][2] = resp.sel_state[6];
        phead_test->select_state[1][3] = resp.sel_state[7];
        phead_test->dumu_state[0][0] = resp.st_pos[0];
        phead_test->dumu_state[0][1] = resp.st_pos[1];
        phead_test->dumu_state[1][0] = resp.st_pos[2];
        phead_test->dumu_state[1][1] = resp.st_pos[3];
        phead_test->sink_state[0][0] = resp.st_pos[4];
        phead_test->sink_state[1][0] = resp.st_pos[5];
        phead_test->dumu_state[0][2] = resp.st_pos[6];
        phead_test->dumu_state[0][3] = resp.st_pos[7];
        phead_test->dumu_state[1][2] = resp.st_pos[8];
        phead_test->dumu_state[1][3] = resp.st_pos[9];
        phead_test->dumu_sensor[0] =  (resp.sensor >> 9) & 0x01;
        phead_test->dumu_sensor[1] = (resp.sensor >> 8) & 0x01;
        phead_test->dumu_sensor[2] =  (resp.sensor >> 4) & 0x01;
        phead_test->dumu_sensor[3] = (resp.sensor >> 3) & 0x01;
        phead_test->dumu_sensor[4] =  (resp.sensor >> 7) & 0x01;
        phead_test->dumu_sensor[5] = (resp.sensor >> 6) & 0x01;
        phead_test->dumu_sensor[6] =  (resp.sensor >> 2) & 0x01;
        phead_test->dumu_sensor[7] = (resp.sensor >> 1) & 0x01;
        phead_test->sink_sensor[0] = resp.sensor & 0x01;
        phead_test->sink_sensor[1] = (resp.sensor >> 5) & 0x01;

    }
    return ret;
}


/*
 * turn off/on green light
 * \param state: 0-off, 1-on
 */
int SwitchGreenLight(PMACHINE pmac, int state)
{
    REQUEST_SIGLIGHT request = {0};
    request.cmd = CMD_REQUEST_SIGLIGHT ;
    request.green = state;
    return cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
}
/*
* turn off/on yellow light
* \param state: 0-off, 1-on
*/
int SwitchYellowLight(PMACHINE pmac, int state)
{
    REQUEST_SIGLIGHT request = {0};
    request.cmd = CMD_REQUEST_SIGLIGHT ;
    request.yellow = state;
    return cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
}
/*
* turn off/on red light
* \param state: 0-off, 1-on
*/
int SwitchRedLight(PMACHINE pmac, int state)
{
    REQUEST_SIGLIGHT request = {0};
    request.cmd = CMD_REQUEST_SIGLIGHT ;
    request.red = state;
    return cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
}
/*
* turn off/on buzzer
* \param state: 0-off, 1-on
*/
int SwitchBuzzer(PMACHINE pmac, int state)
{
    REQUEST_SIGLIGHT request = {0};
    request.cmd = CMD_REQUEST_SIGLIGHT ;
    request.buzzer = state;
    return cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
}
/*
* enable/disable driver of machine
* \param state: 0-disable, 1-enable(lock)
*/
int SwitchMacDriver(int state)
{
    return -1;
}
/*
* run the machine
* \param drt: 0-stop, 1-left, 2-right
* \param speed: between 1-100
*/
int MacRunMotor(PMACHINE pmac, int drt, int speed)
{
    REQUEST_CARRIAGE request;
    request.cmd = CMD_REQUEST_CARRIAGE;
    request.type = drt;       //stop
    request.speed = speed;      //speed
    return cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
}
/*
* run the master rab or high roller
* \param speed: 0-stop, <0-reversal open, >0 normal run
*/
int MacRunRab(PMACHINE pmac, uchar speed, int pulse)
{
    REQUEST_HIGHROLLER request = {0};
    request.cmd = CMD_REQUEST_HIGHROLLER;
    request.speed = speed;
    request.pulse = pulse;
    return cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
}
/*
* run the auxiliary rab or low roller
* \param speed: 0-stop, <0-reversal open, >0 normal run
*/
int MacRunRoller(PMACHINE pmac, int speed)
{
    REQUEST_LOWROLLER request = {0};
    request.cmd = CMD_REQUEST_LOWROLLER;
    request.speed = speed;
    return cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
}
/*
 * run rock
 */
int MacRunRock(PMACHINE pmac, short pos)
{
    int ret = 0;
    REQUEST_ROCK request;
    request.cmd = CMD_REQUEST_ROCK;
    request.pos = pos;
    request.type = 1;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * reset rock
 */
int MacResetRock(PMACHINE pmac)
{
    int ret = 0;
    REQUEST_ROCK request;
    request.cmd = CMD_REQUEST_ROCK;
    request.pos = 0;
    request.type = 0;
    /* 复位 */
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*) &request, sizeof(request));
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}


/*
*
 */
int MacJustResetJijia(PMACHINE pmac, ushort state)
{
    int ret = 0;
    int retry = 2;
    REQUEST_UPGRADE request;
    request.cmd = CMD_REQUEST_RESET_JIJIA;
    request.data = state;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request_just(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
*
 */
int MacResetJijia(PMACHINE pmac, ushort state)
{
    int ret = 0;
    int retry = 2;
    REQUEST_UPGRADE request;
    request.cmd = CMD_REQUEST_RESET_JIJIA;
    request.data = state;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}

/*
*
 */
int MacUpgradeJijia(PMACHINE pmac, ushort state)
{
    int ret = 0;
    int retry = 2;
    REQUEST_UPGRADE request;
    request.cmd = CMD_REQUEST_UPGRADE_JIJIA;
    request.data = state;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}

/*
 * 升级反馈
 */
int MacGetUpgradeFeedback(PMACHINE pmac, uchar *state, uchar *percent)
{
    int ret = -1;
    QUERY_UPGRADE_JIJIA resp = { { 0 } };
    ushort query = CMD_QUERY_UPGRADE_JIJIA;

    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_query(&pmac->st_udp, (uchar*)&query, sizeof (query), (RESPONSE*)&resp, sizeof (resp));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(!ret)
    {
        *state = resp.state;
        *percent = resp.percent;
    }

    return ret;
}


int MacGetSysTime(PMACHINE pmac, int* time_set, int *time_add)
{
    int ret = -1;
    QUERY_SYS_TIME resp = { { 0 } };
    ushort query = CMD_QUERY_SYS_TIME;

    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_query(&pmac->st_udp, (uchar*)&query, sizeof (query), (RESPONSE*)&resp, sizeof (resp));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(!ret)
    {
        *time_set = resp.time_set;
        *time_add = resp.time_add;
    }
    return ret;
}

int MacGetSysId(PMACHINE pmac, char* sys_id)
{
    int ret = -1;
    QUERY_SYS_ID resp = { { 0 } };
    ushort query = CMD_QUERY_SYS_ID;

    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_query(&pmac->st_udp, (uchar*)&query, sizeof (query), (RESPONSE*)&resp, sizeof (resp));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(!ret)
    {
        memcpy(sys_id, resp.id, sizeof(resp.id));
    }
    return ret;
}

/*
 * set state of machine
 * param state: test/run
 */
int MacSendState(PMACHINE pmac, int state)
{
    int ret = 0;
    int retry = 2;
    REQUEST_SET_SYS_STATE request;
    request.cmd = CMD_REQUEST_SET_SYS_STATE;
    request.sys_state = state;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- > 0)
        {
            goto RETRY;
        }
    }

    return ret;
}
/*
* run the yarn feeder machine
* \param drt: 0-left, 1-right
* \param state: 0-off, 1-on
*/
int SwitchYarnFeeder(PMACHINE pmac, int drt, int state)
{
    REQUEST_YF request = {0};
    request.cmd = CMD_REQUEST_YF;
    request.side = drt;
    request.run = state;
    return cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
}
/*
 * get signal of rack om machine
 */
int MacGetRackSignal(PMACHINE pmac, uchar *signal, int size, short *needle)
{
    short query = CMD_QUERY_FB_IN_TEST;
    QUERY_FB_IN_TEST_RESP resp;
    int ret = cmd_query(&pmac->st_udp, (uchar*)&query, sizeof (query), (RESPONSE*)&resp, sizeof (resp));
    if(!ret)
    {
        memcpy(signal, resp.sensor_state, __min(size, sizeof(resp.sensor_state)));
        *needle = resp.needle_num;
    }
    return ret;
}
/*
 * get needle of motor on machine
 */
int MacGetCurrentNeedle(PMACHINE pmac, short *needle)
{
    int ret = 0;
    ushort query = CMD_QUERY_FB_IN_TEST;
    QUERY_FB_IN_TEST_RESP resp = { { 0 } };
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_query(&pmac->st_udp, (uchar*)&query, sizeof (query), (RESPONSE*)&resp, sizeof (resp));
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(!ret)
    {
        *needle = resp.needle_num;
    }
    return ret;
}
/*
 * get pulse of motor on machine
 */
int MacGetCurrentPulse(PMACHINE pmac, int *pulse)
{
    int ret = 0;
    ushort query = CMD_QUERY_FB_IN_TEST;
    QUERY_FB_IN_TEST_RESP resp = { { 0 } };
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_query(&pmac->st_udp, (uchar*)&query, sizeof (query), (RESPONSE*)&resp, sizeof (resp));
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(!ret)
    {
        *pulse = resp.plus_num;
    }
    return ret;
}
/*
 *
 */
int MacGetSysState(PMACHINE pmac, ushort *state, ushort *reset_state)
{
    int ret = -1;
    ushort query = CMD_QUERY_SYS_STATE;
    QUERY_SYS_STATE_RESP state_resp = { {0} };
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_query(&pmac->st_udp, (uchar*)&query, sizeof (query), (RESPONSE*)&state_resp, sizeof (state_resp));
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret >= 0)
    {
        *state = state_resp.resp.state;
        *reset_state = state_resp.reset_state;
    }
    return ret;
}
/*
 * 运行反馈
 */
int MacGetRunFeedback(PMACHINE pmac, RUN_FEEDBACK *pfeed_back)
{
    int ret = -1;
    QUERY_FB_IN_RUN_RESP run_resp = { { 0 } };
    ushort query = CMD_QUERY_FB_IN_RUN;

    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_query(&pmac->st_udp, (uchar*)&query, sizeof (query), (RESPONSE*)&run_resp, sizeof (run_resp));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret >= 0)
    {
        pfeed_back->errcode = run_resp.errcode;
        pfeed_back->mm_state = run_resp.mm_state;
        pfeed_back->rock_state = run_resp.rock_state;
        pfeed_back->needle_num = run_resp.needle_num;
        pfeed_back->row = run_resp.row;
        pfeed_back->cycle_start = run_resp.cycle_start;
        pfeed_back->cycle_end = run_resp.cycle_end;
        pfeed_back->cycle_times = run_resp.cycle_times;
        pfeed_back->cloth_finished = run_resp.cloth_finished;
        pfeed_back->bar_state = run_resp.bar_state;
    }
    return ret;
}
/*
 * start machine
 */
int MacStartMachine(PMACHINE pmac, PMAC_RESET pmac_reset)
{
    char ret = 0;
    pmac->sys_state = SYS_STATE_RESET;
    pmac->run_line = pmac_reset->start_line - 1;
    pmac->sys_state = SYS_STATE_RESET;
    pmac->need_loop = 0;

    REQUEST_RESET request;
    memset(&request, 0, sizeof(REQUEST_RESET));
    request.cmd = CMD_REQUEST_RESET;
    request.nRow = pmac_reset->start_line;//ROW
    memcpy(request.yc_pos, pmac_reset->yarn_init_pos, sizeof(request.yc_pos));
    request.reset_type = pmac_reset->type;
    ret =  cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));

    return ret;
}
/*
 * unlock knit row
 */
int MacUnlockRow(PMACHINE pmac)
{
    int ret = 0;
    REQUEST_LOCKROW request;
    request.cmd = CMD_REQUEST_LOCKROW;
    request.start_row = 0;
    request.end_row = 0;
    request.times = 0;

    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * set machine type
 */
int MacSendMacType(PMACHINE pmac)
{
    int ret = 0;
    REQUEST_SET_MAC_TYPE request;
    request.cmd = CMD_REQUEST_SET_MAC_TYPE;
    request.sys_type = 1;
    request.mac_type = 1;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * lock knit row
 */
int MacLockRow(PMACHINE pmac, int start, int end, int times)
{
    int ret = 0;
    REQUEST_LOCKROW request;
    request.cmd = CMD_REQUEST_LOCKROW;
    request.start_row = start;
    request.end_row = end;
    request.times = times;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    return ret;
}
/*
 * switch yarn
 */
int MacSwitchYarn(PMACHINE pmac, int yarn_switch)
{
    REQUEST_YC_UP request;
    int ret = 0;

    request.cmd = CMD_REQUEST_YC_UP;
    request.dir = yarn_switch;

    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    return ret;
}
/*
 * get running state of machine
 */
int GetMacRunState(PMACHINE pmac)
{
    return pmac->mac_speed_state;
}
/*
 * check reset finished of machine
 */
int GetMacResetStep(PMACHINE pmac)
{
    return pmac->reset_finished;
}
/*
 * check all data send to machine
 */
int MacProbeFinished(PMACHINE pmac)
{
    int send_state = pmac->send_state;
    printf("send_state = %x\n", send_state);
    return ((send_state & ALL_COMPLETE) == ALL_COMPLETE);
}


/***************************************************************************
 * all be feedback from machine in running below
 **************************************************************************/
/*
 * get communication of machine
 */
ushort MacGetCommunication(PMACHINE pmac)
{
    return pmac->resp.resp.state;
}
/*
 * knit line changed of machine
 */
int MacLineChanged(PMACHINE pmac)
{
    return pmac->run_line_change;
}
/*
 * get start of economy
 */
ushort MacEconomyStart(PMACHINE pmac)
{
    return pmac->resp.cycle_start;
}
/*
 * get start of economy
 */
ushort MacEconomyEnd(PMACHINE pmac)
{
    return pmac->resp.cycle_end;
}
/*
 * get end of economy
 */
ushort MacEconomyTimes(PMACHINE pmac)
{
    return 0;
}
/*
 * get left of economy
 */
ushort MacEconomyLeft(PMACHINE pmac)
{
    return pmac->resp.cycle_times;
}
/*
 * get error code of machine
 */
ushort MacGetRunError(PMACHINE pmac)
{
    return pmac->resp.errcode;
}
/*
 * get needle of running
 */
short MacGetRunNeedle(PMACHINE pmac)
{
    return pmac->resp.needle_num;
}
/*
 * get line of running
 */
short MacGetRunLine(PMACHINE pmac)
{
    return pmac->resp.row;
}
/*
 * get hangding of running
 */
char MacGetRockRunState(PMACHINE pmac)
{
    return pmac->resp.rock_state;
}
/*
 * get state of handle
 */
int MacGetHandleState(PMACHINE pmac)
{
    return (pmac->resp.bar_state & 0x03);
}
/*
 * get state of system
 */
int MacGetSystemState(PMACHINE pmac)
{
    return pmac->sys_state;
}
/*
 * set state of system
 */
void MacSetSystemState(PMACHINE pmac, int state)
{
    pmac->sys_state = state;
}

/********************************************************************************
 * modify the param of machine below
 ********************************************************************************/
/*
 * set economy of machine
 */
int MacSetEconomy(PMACHINE pmac, ushort total, ushort start, ushort end, ushort times)
{
    int ret = 0;
    MODIFY modify = { 0 };
    ushort buf[3] = {0};
    if(times)
    {
        buf[0] = start;
        buf[1] = end;
        buf[2] = times;
    }
    int total_size = sizeof(KNIT_PAGE) * (total + 1);
    modify.cmd = CMD_MODIFY_CNT;
    modify.total_size = total_size;
    modify.offset = end * sizeof(KNIT_PAGE) + 122;
    modify.size = sizeof(buf);
    modify.content = (uchar*)buf;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_modify(&pmac->st_udp, &modify);
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * send total cloth
 */
int MacSetClothNum(PMACHINE pmac, ushort done, ushort total)
{
    int retry = 2;
    int ret = 0;

    ushort num[2];
    num[0] = done;
    num[1] = total;

    MODIFY modify = { 0 };
    modify.cmd = CMD_MODIFY_CLOTHNUM;
    modify.offset = 0;
    modify.content =  (uchar*)num;
    modify.total_size = sizeof(num);
    modify.size = sizeof(num);
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_modify(&pmac->st_udp, &modify);
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        retry--;

        if (retry < 0)
        {
            return -1;
        }
        goto RETRY;
    }

    printf("send clothnum file success\n");
    return 0;
}
/*
 * set speed of motor on machine
 * param sect: from 0 to 31
 */
int MacSetMotorSpeed(PMACHINE pmac, uint sect, uchar speed)
{
    int ret = 0;
    MODIFY modify = { 0 };
    modify.cmd = CMD_MODIFY_SPEED;
    modify.total_size = SECT_NUM * 6;
    modify.size = 1;
    modify.offset = sect;
    modify.content = &speed;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_modify(&pmac->st_udp, &modify);
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * set all speed of motor on machine
 */
int MacSetAllMotorSpeed(PMACHINE pmac, uchar *pspeed)
{
    int ret = 0;
    MODIFY modify = { 0 };
    modify.cmd = CMD_MODIFY_SPEED;
    modify.total_size = SECT_NUM * 6;
    modify.size = SECT_NUM;
    modify.offset = 0;
    modify.content = pspeed;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_modify(&pmac->st_udp, &modify);
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * set speed of rab on machine
 * param sect: from 0 to 31
 */
int MacSetRabSpeed(PMACHINE pmac, uint sect, uchar speed)
{
    int ret = 0;
    MODIFY modify = { 0 };
    modify.cmd = CMD_MODIFY_SPEED;
    modify.total_size = SECT_NUM * 6;
    modify.size = 1;
    modify.offset = SECT_NUM + sect;
    modify.content = &speed;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_modify(&pmac->st_udp, &modify);
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * set all speed of rab machine
 * param sect: from 0 to 31
 */
int MacSetAllRabSpeed(PMACHINE pmac, uchar *pspeed)
{
    int ret = 0;
    MODIFY modify = { 0 };
    modify.cmd = CMD_MODIFY_SPEED;
    modify.total_size = SECT_NUM * 6;
    modify.size = SECT_NUM;
    modify.offset = SECT_NUM;
    modify.content = pspeed;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_modify(&pmac->st_udp, &modify);
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * set dumu of machine
 * param f0b1: 0-front, 1-back
 * param which: 0-3
 * param sect: 0-31
 */
int MacSetDumu(PMACHINE pmac, uint f0b1, uint which, uint sect, ushort dumu)
{
    int ret = 0;
    int offset = 0;
    if(f0b1)
    {
        if(which)//back2
        {
            offset = SECT_NUM + sect;
        }
        else
        {
            offset = SECT_NUM * 4 + sect;
        }
    }
    else
    {
        if(which)//front2
        {
            offset = sect;
        }
        else
        {
            offset = SECT_NUM * 3 + sect;
        }
    }
    MODIFY modify = { 0 };
    modify.cmd = CMD_MODIFY_STITCH;
    modify.total_size = SECT_NUM * 5;
    modify.size = sizeof(ushort);
    modify.offset =  offset;
    modify.content = (uchar*)&dumu;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_modify(&pmac->st_udp, &modify);
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * set stop of yarn on machine
 */
int MacSetYarnStop(PMACHINE pmac, uint l0r1, uint which, uint sect, uchar stop)
{
    int ret = 0;
    int offset = 32 * sect + l0r1 * 16 + which;
    MODIFY modify = { 0 };
    modify.cmd = CMD_MODIFY_YCPARKPOS;
    modify.total_size = sizeof(YARN_STOP);
    modify.size = sizeof(uchar);
    modify.offset = offset;
    modify.content = &stop;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_modify(&pmac->st_udp, &modify);
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * send data of yarn_befor_set
 */
int MacSendYarnBeforeSet(PMACHINE pmac, char *data, uint num, uint offset)
{
    int ret = 0;
    uchar retry = 3;
    MODIFY modify = { 0 };
    modify.cmd = CMD_MODIFY_YARNBEFOR;
    modify.total_size =  sizeof (YARN_BEFORE_NEEDLE);
    modify.size = num;
    modify.offset = offset;
    modify.content = (uchar *)data;;
YARNBEFORE_RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_modify(&pmac->st_udp, &modify);
    pthread_mutex_unlock(&pmac->udp_mutex);

    if (ret < 0)
    {
        if (retry-- < 0)
        {
            return -1;
        }
        goto YARNBEFORE_RETRY;
    }
    return ret;
}
/*
 * send rock data to machine
 */
int MacSendRockData(PMACHINE pmac, PROCK_POS prock_pos)
{
    return rock_send_file(&pmac->st_udp, prock_pos, &pmac->udp_mutex);
}
/*
 * send system param
 */
int MacSendSysParam(PMACHINE pmac, PSYS_PARAM psys_param)
{
    return sysprm_send_file(&pmac->st_udp, psys_param);
}
/*
 * send work param
 */
int MacSendWorkParam(PMACHINE pmac, PWORK_PARAM pwork_param)
{
    return workprm_send_file(&pmac->st_udp, pwork_param);
}
/*
*send hide work param
*/
int MacSendHideParam(PMACHINE pmac, PHIDE_PARAM phide_param)
{
    return hideprm_send_file(&pmac->st_udp, phide_param);
}
/*
 *
 */
int MacSendPartsParam(PMACHINE pmac, PMAC_PARAM pmac_param)
{
    return macparam_send_file(&pmac->st_udp, pmac_param);
}
/*
 *
 */
int MacSendAlarmMask(PMACHINE pmac, PALARM_MASK palarm)
{
    return alarmmask_send_file(&pmac->st_udp, palarm, &pmac->udp_mutex);
}
/*
 *
 */
int MacSendBeforeCom(PMACHINE pmac, PYARN_BEFORE_NEEDLE pyarn_before_needle)
{
    return yarn_before_send_file(&pmac->st_udp, pyarn_before_needle);
}
/*
 * send exchanged yarn
 */
int MacSendExchangedYarn(PMACHINE pmac, PYARN_EXCHANGE pyarn_exchange)
{
    return yarn_exchange_send_file(&pmac->st_udp, pyarn_exchange, &pmac->udp_mutex);
}
/*
 * send board set param
 */
 int MacSendBoardParam(PMACHINE pmac, PBOARD_PARAM pboard)
 {
     return board_param_send_file(&pmac->st_udp, pboard, &pmac->udp_mutex);
 }
/*
 * send jijia upgrade file
 */
 int MacSendJijiaUpgrade(PMACHINE pmac, uchar *data, int file_size)
 {
     return jijia_upgrade_send_file(&pmac->st_udp, data, file_size, &pmac->udp_mutex);
 }



/*
 * send one line of control data
 */
int MacSendConLine(PMACHINE pmac, PKNIT_PAGE pcon, ushort total, ushort line)
{
    int ret = 0;
    int retry = 3;
    MODIFY modify = { 0 };
    modify.cmd = CMD_MODIFY_CNT;
    modify.total_size = (total + 1) * sizeof(KNIT_PAGE);
    modify.offset = line * sizeof(KNIT_PAGE);
    modify.size = sizeof(KNIT_PAGE);
    modify.content = (uchar*)pcon;

CNT_RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_modify(&pmac->st_udp, &modify);
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        retry--;

        if(retry < 0)
        {
            return -1;
        }
        goto CNT_RETRY;
    }

    return 0;
}
/*
 * send control data
 */
int MacSendControlData(PMACHINE pmac, KNIT_PAGE *pcon, ushort total)
{
    return program_send_file(&pmac->st_udp, pcon, total);
}
/*
 * send flower data
 */
int MacSendFlowerData(PMACHINE pmac, uchar *pflw, ushort width, ushort height)
{
    return pe_send_file(&pmac->st_udp, pflw, width, height);
}
/*
 * send speed param
 */
int MacSendSpeedParam(PMACHINE pmac, PMH_SPEED pspeed)
{
    return speed_send_file(&pmac->st_udp, pspeed, &pmac->udp_mutex);
}
/*
 * send dumu param
 */
int MacSendDumuParam(PMACHINE pmac, PMH_DUMU pdumu)
{
    return dumu_send_file(&pmac->st_udp, pdumu, &pmac->udp_mutex);
}
/*
 * send dmbz param
 */
int MacSendDmbzParam(PMACHINE pmac, PSTITCH_AMEND psa)
{
    return dmbz_send_file(&pmac->st_udp, psa, &pmac->udp_mutex);
}
/*
 * send sink param
 */
int MacSendSinkParam(PMACHINE pmac, SINK_PIECE psa)
{
    return sink_send_file(&pmac->st_udp, psa, &pmac->udp_mutex);
}
/*
 * send cam param
 */
int MacSendCamParam(PMACHINE pmac, CAM_PIECE psa)
{
    return cam_send_file(&pmac->st_udp, psa, &pmac->udp_mutex);
}
/*
 * send yarn feeder param
 */
int MacSendYarnFeederParam(PMACHINE pmac, YARNFEEDER_PIECE yarndata)
{
    return yarn_feed_send_file(&pmac->st_udp,  yarndata, &pmac->udp_mutex);
}
/*
 * send yarn stop
 */
int MacSendYarnStopParam(PMACHINE pmac, PYARN_STOP pyarn_stop)
{
    return yarn_stop_send_file(&pmac->st_udp, pyarn_stop);
}
/*
 * send stop line
 */
int MacSendStopLine(PMACHINE pmac, ushort line)
{
    int ret = 0;
    REQUEST_STOPLINE request;
    request.cmd = CMD_REQUEST_STOPLINE;
    request.nRow = line;
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);
    return ret;
}
/*
 * send piece lock
 */
int MacSendPieceLock(PMACHINE pmac, uchar lock)
{
    int ret = 0;
    REQUEST_PIECELOCK request = { 0 };
    int retry = 1;
    request.cmd = CMD_REQUEST_PIECELOCK;
    request.lock = lock;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        --retry;
        if(retry < 0)
        {
            return -1;
        }
        goto RETRY;
    }
    return ret;
}
/*
 * send speed of machine
 */
int MacSendMacSpeed(PMACHINE pmac, uchar speed)
{
    int ret = 0;
    REQUEST_MACSPEED request = { 0 };
    int retry = 1;
    request.cmd = CMD_REQUEST_SPEED;
    request.speed = speed;
RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);
    if(ret < 0)
    {
        --retry;
        if(retry < 0)
        {
            return -1;
        }
        goto RETRY;
    }
    return ret;
}
/*
 * send speed of machine
 */
int MacSendSysTime(PMACHINE pmac, int set_time, int add_time, ushort lock)
{
    int ret = 0;
    REQUEST_SETTIME request = { 0 };
    int retry = 1;
    request.cmd = CMD_REQUEST_SET_SYS_TIME;
    request.set_time = set_time;
    request.add_time = add_time;
    request.lock = lock;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        --retry;
        if(retry < 0)
        {
            return -1;
        }
        goto RETRY;
    }
    return ret;
}
/*
 * send type of machine
 */
int MacSendMachineType(PMACHINE pmac, ushort sys_type, ushort mac_type)
{
    int ret = 0;
    REQUESET_MACTYPE request = { 0 };
    int retry = 1;
    request.cmd = CMD_REQUEST_SET_MAC_TYPE;
    request.sys_type = sys_type;
    request.mac_type = mac_type;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        --retry;
        if(retry < 0)
        {
            return -1;
        }
        goto RETRY;
    }
    return ret;
}
/*
 * send save data
 */
int MacSendSaveData(PMACHINE pmac, ushort data)
{
    int ret = 0;
    REQUESET_SAVEDATA request = { 0 };
    int retry = 1;
    request.cmd = CMD_REQUEST_SAVE_DATA;
    request.data = data;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_request(&pmac->st_udp, (uchar*)&request, sizeof (request));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        --retry;
        if(retry < 0)
        {
            return -1;
        }
        goto RETRY;
    }
    return ret;
}
/*
 * send extent piece data
 */
int MacSendExtentPieceData(PMACHINE pmac, PEXT_PIECE pext_piece)
{
    return extpiece_send_file(&pmac->st_udp, pext_piece, &pmac->udp_mutex);
}
/*
 * get version info
 */
int MacGetVersionInfo(PMACHINE pmac, VERSION *pversion)
{
    int ret = 0;
    short query = CMD_QUERY_VERSION;
    QUERY_VERSION resp = { { 0 } };
    int retry = 2;

RETRY:
    pthread_mutex_lock(&pmac->udp_mutex);
    ret = cmd_query(&pmac->st_udp, (uchar*)&query, sizeof (query), (RESPONSE*)&resp, sizeof (QUERY_VERSION));
    pthread_mutex_unlock(&pmac->udp_mutex);

    if(ret < 0)
    {
        if(retry-- <= 0)
        {
            return -1;
        }
        goto RETRY;
    }

    pversion->header[0] = resp.carriage >> 8;
    pversion->header[1] = resp.carriage;
    pversion->header[2] = resp.carriage_bl >> 8;
    pversion->header[3] = resp.carriage_bl;

    pversion->rack[0] = resp.rack >> 8;
    pversion->rack[1] = resp.rack;
    pversion->rack[2] = resp.rack_bl >> 8;
    pversion->rack[3] = resp.rack_bl;

    pversion->board[0] = resp.comb >> 8;
    pversion->board[1] = resp.comb;
    pversion->board[2] = resp.comb_bl >> 8;
    pversion->board[3] = resp.comb_bl;

    return ret;
}
/*
 * @note:发送前缀编织数据给下位机,1次发1行
 */
int MacSendPkCon(PMACHINE pmac, uchar *pcon, ushort height, uchar type)
{
    int ret = 0;
    int retry = 2;
    MODIFY modify = { 0 };
    int total_size = 0;
    int n = 0;
    int i = 0;
    uchar buf[sizeof(KNIT_PAGE)] = { 0 };
    printf("send pk con type:%d, height:%d\n",type, height);
    n = height + 1;
    total_size = n * sizeof(KNIT_PAGE);

    modify.cmd = CMD_MODIFY_PK_CON;
    modify.total_size = total_size;
    modify.size = sizeof(KNIT_PAGE);
    modify.content = buf;

    for (i = 0; i < n; i++)
    {
        retry = 2;

        if (i == 0)
        {
            memset(buf, 0, sizeof (buf));
            buf[0] = type;
        }
        else
        {
            uchar *ptmp = pcon + (i - 1) * sizeof(KNIT_PAGE);
            memcpy(buf, ptmp, sizeof(KNIT_PAGE));
        }

        modify.offset = i * sizeof(KNIT_PAGE);

RETRY:
        pthread_mutex_lock(&pmac->udp_mutex);
        ret = cmd_modify(&pmac->st_udp, &modify);
        pthread_mutex_unlock(&pmac->udp_mutex);

        if (ret < 0)
        {
            if (retry-- <= 0)
            {
                return -1;
            }
            goto RETRY;
        }
    }

    return ret;
}
/*
 * 发送花样给下位机,1次发1行
 */
int MacSendPkDat(PMACHINE pmac, uchar *dat, ushort width, ushort height)
{
    int i = 0;
    int retry = 2;
    MODIFY modify = { 0 };
    int ret = 0;
    int rows = 0;
    uchar *buf = NULL;

    printf("width = %d, height = %d\n", width, height);

    rows = height + 1;
    modify.cmd = CMD_MODIFY_PK_DAT;
    modify.total_size = rows * width;
    modify.offset = 0;

    buf = (uchar*)malloc(width);

    for (i = 0; i < rows; i++)
    {
        if (i == 0)
        {
            memset(buf, 0, width);
            buf[0] = width & 0x00FF;
            buf[1] = (width & 0xFF00) >> 8;
            buf[2] = height & 0x00FF;
            buf[3] = (height & 0xFF00) >> 8;
        }
        else
        {
            memcpy(buf, dat + (i - 1) * width, width);
        }

        modify.size = width;
        modify.offset = i * width;
        modify.content = buf;

RETRY:
        pthread_mutex_lock(&pmac->udp_mutex);
        ret = cmd_modify(&pmac->st_udp, &modify);
        pthread_mutex_unlock(&pmac->udp_mutex);

        if (ret < 0)
        {
            if (retry-- <= 0)
            {
                goto FAILED;
            }
            goto RETRY;
        }
    }

FAILED:
    FREE(buf);
    return ret;
}



#endif
